
/**
 * 详细解释 https://blog.csdn.net/qq_40028324/article/details/123291592?spm=1001.2014.3001.5501
 */


function deepClone (obj, hash = new WeakMap()) {
  if (obj == null) return obj
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)
  if (typeof obj !== 'object') return obj

  if (hash.has(obj)) return hash.get(obj)

  let deepObj = new obj.constructor

  hash.set(obj, deepObj)
  for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
      deepObj[key] = deepClone(obj[key], hash);
    }
  }
  return deepObj
}

let testobj = { a: 1, b: { c: '2' } } // { a: 1, b: { c: '2' } }
testobj.b.c = testobj // <ref *1> { a: 1, b: { c: [Circular *1] } }
console.log(deepClone(testobj));

let testArr = [1, 2, { a: [3, 4] }]
console.log(deepClone(testArr)); // [ 1, 2, { a: [ 3, 4 ] } ]
